﻿using System;
using System.Collections.Generic;

using SIMA.Entities;
using SIMA.Core.Data.Collection;
using SIMA.Core.Data.Access;
using System.Threading;
using SIMA.Core.EventArgs;
using SIMA.Core.Security;

namespace SIMA.Services
{
    // NOTA: si cambia aquí el nombre de clase "PerfilService", también debe actualizar la referencia a "PerfilService" en App.config.
    public class PerfilService : IPerfilService
    {
        SmartContainer<T_C_Perfil> perfilSmart;
        private FailedEventArgs onFailed;
        private InsertedEventArgs onInserted;
        private UpdatedEventArgs onUpdated;
        private DeletedEventArgs onDeleted;
        private static Semaphore ResourceLock;

        public PerfilService()
        {
            DataAccess.SetConnection(SIMA.Core.Enums.AccessType.FromString, "Data Source=.;Initial Catalog=SIMA;Integrated Security=True");
            ResourceLock = new Semaphore(0, 2);
            perfilSmart = new SmartContainer<T_C_Perfil>(false,true);
            perfilSmart.Inserted += new EventHandler<InsertedEventArgs>(perfilSmart_Inserted);
            perfilSmart.Failed += new EventHandler<FailedEventArgs>(perfilSmart_Failed);
            perfilSmart.Updated += new EventHandler<UpdatedEventArgs>(perfilSmart_Updated);
            perfilSmart.Deleted += new EventHandler<DeletedEventArgs>(perfilSmart_Deleted);
        }

        void perfilSmart_Deleted(object sender, DeletedEventArgs e)
        {
            onDeleted = e;
        }

        void perfilSmart_Updated(object sender, UpdatedEventArgs e)
        {
            onUpdated = e;
        }

        void perfilSmart_Failed(object sender, FailedEventArgs e)
        {
            onFailed = e;
        }

        void perfilSmart_Inserted(object sender, InsertedEventArgs e)
        {
            onInserted = e;
        }

        
        #region Miembros de IPerfilService

        public System.Collections.Generic.List<SIMA.Entities.T_C_Perfil> GetPerfiles(Profile securityProfile)
        {
            SecurityProgram.PcProfile = securityProfile;
            perfilSmart.SelectAll();
            
            return perfilSmart.ToList();
        }

        public IAsyncResult BeginGetPerfiles(SIMA.Core.Security.Profile securityProfile, AsyncCallback callback, object state)
        {
            PerfilesAsyncResult asyncResult = new PerfilesAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((GetPerfilesCallback)), asyncResult);
            return asyncResult;

        }

        private void GetPerfilesCallback(object asyncResult)
        {
            PerfilesAsyncResult getPerfilesAsyncResult = (PerfilesAsyncResult)asyncResult;
            try
            {
                getPerfilesAsyncResult.CollectionResult = GetPerfiles(getPerfilesAsyncResult.Profile);
                getPerfilesAsyncResult.ExceptionTrace = null;
                getPerfilesAsyncResult.MessageResult = string.Empty;
            }
            catch (Exception ex)
            {
                getPerfilesAsyncResult.CollectionResult = null;
                getPerfilesAsyncResult.ExceptionTrace = ex;
                getPerfilesAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                getPerfilesAsyncResult.OnCompleted();
            }
        }

        public System.Collections.Generic.List<SIMA.Entities.T_C_Perfil> EndGetPerfiles(IAsyncResult asyncResult)
        {
            System.Collections.Generic.List<SIMA.Entities.T_C_Perfil> perfiles = null;
            using (PerfilesAsyncResult getPerfilesResult = asyncResult as PerfilesAsyncResult)
            {
                getPerfilesResult.AsyncWaitHandle.WaitOne();
                perfiles = getPerfilesResult.CollectionResult;
            }

            return perfiles;
        }

        public List<SIMA.Entities.T_C_Perfil> GetPerfilesFiltered(SIMA.Core.Security.Profile securityProfile, SIMA.Core.Enums.FilterType filter)
        {
            throw new NotImplementedException();
        }

        public IAsyncResult BeginGetPerfilesFiltered(SIMA.Core.Security.Profile securityProfile, SIMA.Core.Enums.FilterType filter, AsyncCallback callback, object state)
        {
            throw new NotImplementedException();
        }

        public List<SIMA.Entities.T_C_Perfil> EndGetPerfilesFiltered(IAsyncResult asyncResult)
        {
            throw new NotImplementedException();
        }

        public string NewPerfil(SIMA.Core.Security.Profile securityProfile, SIMA.Entities.T_C_Perfil newPerfil)
        {
            perfilSmart.Add(newPerfil);
            ResourceLock.WaitOne(1000);
            return "Nuevo registro de perfil creado.";
        }

        public IAsyncResult BeginNewPerfil(SIMA.Core.Security.Profile securityProfile, SIMA.Entities.T_C_Perfil newPerfil, AsyncCallback callback, object state)
        {
            PerfilesAsyncResult asyncResult = new PerfilesAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((NewPerfilCallback)),asyncResult);
            return asyncResult;
        }

        private void NewPerfilCallback(object asyncResult)
        {
            PerfilesAsyncResult newPerfilAsyncResult = (PerfilesAsyncResult)asyncResult;
        }

        public string EndNewPerfil(IAsyncResult asyncResult)
        {
            throw new NotImplementedException();
        }

        public string UpdatePerfil(SIMA.Core.Security.Profile securityProfile, SIMA.Entities.T_C_Perfil perfilToUpdate, SIMA.Entities.T_C_Perfil perfilUpdated)
        {
            throw new NotImplementedException();
        }

        public IAsyncResult BeginUpdatePerfil(SIMA.Core.Security.Profile securityProfile, SIMA.Entities.T_C_Perfil perfilToUpdate, SIMA.Entities.T_C_Perfil perfilUpdated, AsyncCallback callback, object state)
        {
            throw new NotImplementedException();
        }

        public string EndUpdatePerfil(IAsyncResult asyncResult)
        {
            throw new NotImplementedException();
        }

        public string DeletePerfil(SIMA.Core.Security.Profile securityProfile, SIMA.Entities.T_C_Perfil PerfiltoDelete)
        {
            throw new NotImplementedException();
        }

        public IAsyncResult BeginDeletePerfil(SIMA.Core.Security.Profile securityProfile, SIMA.Entities.T_C_Perfil PerfiltoDelete, AsyncCallback callback, object state)
        {
            throw new NotImplementedException();
        }

        public string EndDeletePerfil(IAsyncResult asyncResult)
        {
            throw new NotImplementedException();
        }

        public List<SIMA.Entities.T_C_Perfil> CallProcedure(SIMA.Core.Security.Profile securityProfile, string param, SIMA.Core.Enums.CommandType commandType)
        {
            throw new NotImplementedException();
        }

        public IAsyncResult BeginCallProcedure(SIMA.Core.Security.Profile securityProfile, string param, SIMA.Core.Enums.CommandType commandType, AsyncCallback callback, object state)
        {
            throw new NotImplementedException();
        }

        public List<SIMA.Entities.T_C_Perfil> EndCallProcedure(IAsyncResult asyncResult)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
